#ifndef __DEBUG_SHELL__
#define __DEBUG_SHELL__

#include <string.h>
#include <fstream>
#include <iostream>

#include "avr.h"

class DebugShell
{
public:
  DebugShell (AVR& avr);

  void run ();

private:
  AVR& _avr;

  uint16_t assemble_instruction (const string& instruction);

  static void print_help ();
  template<typename T>
  static void print_memory_region (T* memory, uint16_t addr, uint16_t cnt)
  {
    ofstream fmt;
    fmt.copyfmt (cout);

    int bpl = 16;
    if ((sizeof (T) * 2 + 1) * bpl + 5 > 80)
      bpl = 75 / (sizeof (T) * 2 + 1);

    cout << "     ";
    cout.flags (ios::left);
    for (int i = 0; i < bpl; ++i) {
      cout.width (sizeof (T) * 2 + 1);
      cout << hex << (int)i;
    }

    for (int i = 0; i < cnt; ++i) {
      if (i % bpl == 0) {
        cout << endl;
        cout.flags (ios::right);
        cout.width (4);
        cout.fill ('0');
        cout << hex << (i + addr);
        cout << ' ';
      }

      cout.flags (ios::left);
      cout.width (sizeof (T) * 2);
      cout << hex << (int)memory[i];
      cout << ' ';
    }

    cout << endl;
    cout.copyfmt (fmt);
  }
};

#endif
